/**
 * File : M_mock.js
 * By : Minglie
 * QQ: 934031452
 * Date :2021.12.05
 * version :2.5.0
 */
(function (window, undefined) {

    const M = {};

    M.requestFailHandel = async (url, Resdata) => {

        return
    }
    M.Component = {};
    ////////////////////////////////////////////
    M.cache_req_data_enable = false;

    M._global_state = {}

    M._globle_cacheMap = {}

    M._globle_lib_cacheMap = {}

    M._globle_plugin_url_cacheMap = {};

    M._globle_plugin = new Set();

    M.getGloblePlugin = (pluginKey) => {
        let plugin = null;
        M._globle_plugin.forEach(u => {
            if (u.key == pluginKey) {
                plugin = u;
            }
        })
        return plugin;
    }

    const App = {
        _get: {},
        _begin: function () {
        },
        _end: function () {
        },
        begin(callback) {
            App._begin = callback;
        },
        end(callback) {
            App._end = callback;
        },
        use(url, callback) {
            if (typeof url === 'function' || typeof url === 'object') {
                let plugin = url;
                let args = callback;
                if (plugin.installed) {
                    return App;
                }
                if (typeof plugin === 'function') {
                    plugin(App, args);
                } else {
                    plugin.install(App, args);
                }
                plugin.installed = true;
                M._globle_plugin.add(plugin);
            }
            return App;
        },
        async installPlugin(pluginUrl, constructorParams, pluginParams) {
            if (M._globle_plugin_url_cacheMap[pluginUrl]) {
                return
            }
            M._globle_plugin_url_cacheMap[pluginUrl] = pluginUrl;
            return new Promise(resolve => {
                import(pluginUrl).then(async modul => {
                    const Plugin = modul.default;
                    const plugin = new Plugin(constructorParams);
                    App.use(plugin, pluginParams)
                    resolve(plugin);
                })

            })
        },

        /**
         * ע��get����
         */
        get(methodName, callback) {
            M.IO.reg(methodName.replace("/", ""));
            App._get[methodName] = callback;
        },
        async doget(methodName, params, callback) {
            const req = {};
            const res = {};
            req.url = methodName;
            req.params = params;
            await App._begin(req, res);
            res.send = function (d) {
                callback(d);
            }.bind(this);
            App._get[methodName](req, res);
        }
    };


    M.sleep = function (numberMillis) {
        let now = new Date();
        let exitTime = now.getTime() + numberMillis;
        while (true) {
            now = new Date();
            if (now.getTime() > exitTime) {
                return;
            }
        }
    };

    M.delayMs = async function (ms) {
        return new Promise(r => {
            setTimeout(() => {
                r(1)
            }, ms)
        })
    }


    M.randomStr = function () {
        return (Math.random().toString(36) + new Date().getTime()).slice(2);
    };

    M.urlStringify = function (obj) {
        if (obj !== null && typeof obj === 'object') {
            let keys = Object.keys(obj);
            let len = keys.length;
            let flast = len - 1;
            let fields = '';
            for (let i = 0; i < len; ++i) {
                let k = keys[i];
                let v = obj[k];
                let ks = k + "=";
                fields += ks + v;
                if (i < flast) {
                    fields += "&";
                }
            }
            return fields;
        }
        return '';
    };

    M.urlParse = function (url) {
        url = url.substr(url.indexOf("?") + 1);
        let t, n, r, i = url, s = {};
        t = i.split("&"),
            r = null,
            n = null;
        for (let o in t) {
            let u = t[o].indexOf("=");
            u !== -1 && (r = t[o].substr(0, u),
                n = t[o].substr(u + 1),
                s[r] = n);
        }
        return s
    };


    M.formatUrl = function (url) {
        if (url.indexOf("?") > 0) {
            url = url.substr(0, url.indexOf("?"));
        } else {
            url = url;
        }
        if (!url.endsWith('/')) {
            url = url + '/';
        }
        if (!url.startsWith('/')) {
            url = '/' + url;
        }
        return url;
    };


    M.encodeURIComponentObj = function (data) {
        let ret = '';
        for (let it in data) {
            ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&';
        }
        return ret
    };



    M.fileDownload = function (content, filename) {
        let eleLink = document.createElement('a');
        eleLink.download = filename;
        eleLink.style.display = 'none';
        let blob = new Blob([content]);
        eleLink.href = URL.createObjectURL(blob);
        document.body.appendChild(eleLink);
        eleLink.click();
        document.body.removeChild(eleLink);
    };


    M.getParameter = function (name) {
        let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        let r = window.location.href.substr(window.location.href.indexOf('?')).substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    };



    M.IO = {};
    M.IO.reg = function (methed, type) {
        M.IO[methed] = (param) => {
            return new Promise(
                function (reslove) {
                    App.doget("/" + methed, param, (d) => {
                        reslove(d);
                    })
                }
            )
        }
    };


    M.SetStateSession = (state) => {
        sessionStorage.setItem('state', JSON.stringify(state));
    }

    M.GetStateSession = () => {
        return JSON.parse(sessionStorage.getItem('state'));
    }

    M.RemoveStateSession = () => {
        sessionStorage.removeItem('state');
    }

    M.init = function () {
        Date.prototype.format = function (fmt) {
            let o = {
                "M+": this.getMonth() + 1,
                "d+": this.getDate(),
                "h+": this.getHours(),
                "m+": this.getMinutes(),
                "s+": this.getSeconds(),
                "q+": Math.floor((this.getMonth() + 3) / 3),
                "S": this.getMilliseconds()
            };
            if (/(y+)/.test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            }
            for (let k in o) {
                if (new RegExp("(" + k + ")").test(fmt)) {
                    fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                }
            }
            return fmt;
        }
    };

    M.urlToPath = function (url) {
        return url.replace(/^http(s?):\/\/[^/]+/, "");
    };

    M.beforeSend = function (options) {

        return true;
    };
    M.endResponse = function (data, xhr) {
        return data;
    };


    const translateApi = (api) => {
        let url = M.config ? M.config.baseUrl(api) : api;
        if (!api.startsWith("http")) {
            api = url
        }
        return api;
    }

    const request = async function ({ methed, api, params, headers }) {
        api = translateApi(api)
        headers = Object.assign({ 'Content-Type': 'application/json' }, headers);
        if (window.M.config.token) {
            headers.token = window.M.config.token;
        }
        return new Promise((reslove, reject) => {
            fetch(api, {
                method: methed,
                mode: 'cors',
                headers: headers,
                body: JSON.stringify(params)
            }).then(function (response) {
                return response.json();
            }).then((res) => {
                M.requestFailHandel(api, res);
                reslove(res);
            }).catch((err) => {
                console.error(err);
                reject(err);
            });
        })
    }

    const post = async (api, params = {}, headers) => request({ methed: "POST", api, params, headers })
    const del = async (api, params = {}, headers) => request({ methed: "DELETE", api, params, headers })
    const put = async (api, params = {}, headers) => request({ methed: "PUT", api, params, headers })
    const get = async (api, params = {}, headers) => {
        api = translateApi(api)
        let getData = "";
        if (params) {
            getData = window.M.urlStringify(params);
            if (api.indexOf("?") > 0) {
                getData = "&" + getData;
            } else {
                getData = "?" + getData;
            }
        }
        api = api + getData;
        headers = Object.assign({ 'Content-Type': 'application/json' }, headers);
        if (window.M.config.token) {
            headers.token = window.M.config.token;
        }
        return new Promise((reslove, reject) => {
            fetch(api, {
                method: 'GET',
                mode: 'cors',
                headers: headers
            }).then(function (response) {
                return response.json();
            }).then((res) => {
                M.requestFailHandel(api, res);
                reslove(res)
            }).catch((err) => {
                console.error(err);
                reject(err)
            });
        })
    };
    const jsonp = async (url, callbackFunction) => {
        return new Promise(resolve => {
            let callbackStr = M.urlParse(url).callback;
            window[callbackStr] = (...params) => {
                if (callbackFunction) {
                    callbackFunction(params);
                }
                document.body.removeChild(document.getElementById("ming_mock_jsonp_id"))
                resolve(params);
            }
            var scriptElement = document.createElement('script');
            scriptElement.src = url;
            scriptElement.id = "ming_mock_jsonp_id"
            document.body.appendChild(scriptElement);
        })
    };

    M.init();
    window.app = App;
    window.M = M;
    window.MIO = M.IO;
    window.M.request = {}
    window.M.request.get = get;
    window.M.request.post = post;
    window.M.request.delete = del;
    window.M.request.put = put;
    window.M.request.jsonp = jsonp;
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = { app: App, M, MIO: M.IO }
    }

})(window);